<template>
  <div class="info-manage">
    <el-tabs v-model="activeName">
      <el-tab-pane label="昵称" name="nickName">
        <input
          class="info-manage__nickname"
          ref="nickNameRef"
          autocomplete="false"
          maxlength="8"
          :disabled="isLoading__nickName"
          :value="nickName"
          @compositionstart="compositStart"
          @compositionend="compositEnd"
          @input="handleInput($event)"
          @keyup.enter.prevent="isChangeNickName"
        /><el-button
          style="margin-left: 30px"
          type="primary"
          :disabled="!nickName || isLoading__nickName"
          :loading="isLoading__nickName"
          @click="changeNickName"
          ><template #loading><Loading /></template>更改</el-button
        >
      </el-tab-pane>
      <el-tab-pane label="性别" name="sex">
        <el-radio-group
          style="margin-top: 20px"
          v-model="userInfo.sex"
          :disabled="isLoading__sex"
        >
          <el-radio label="男" size="large">男</el-radio>
          <el-radio label="女" size="large">女</el-radio> </el-radio-group
        ><el-button
          style="margin-left: 50px"
          type="primary"
          :disabled="isLoading__sex"
          :loading="isLoading__sex"
          @click="changeSex"
          ><template #loading><Loading /></template>确定</el-button
        >
      </el-tab-pane>
      <el-tab-pane label="生日" name="birthday"
        ><div class="info-manage__birth">
          <select-birth
            v-model:birthday="userInfo.birthday"
            :disabled="isLoading__birthday"
            :show-title="false"
          ></select-birth>
        </div>
        <el-button
          class="info-manage__birth--button"
          type="primary"
          :disabled="isLoading__birthday"
          :loading="isLoading__birthday"
          @click="changeBirth"
          ><template #loading><Loading /></template>确认</el-button
        ></el-tab-pane
      >
      <el-tab-pane label="地区" name="area">
        <div style="width: 70%">
          <select-area
            :data="areaDatas"
            v-model="userInfo.areaCoord"
            :disabled="isLoading__area"
          ></select-area>
        </div>
        <el-button
          class="info-manage__area--button"
          type="primary"
          :disabled="isLoading__area"
          :loading="isLoading__area"
          @click="changeArea"
          ><template #loading><Loading /></template>确认</el-button
        >
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, customRef, onMounted, watch, nextTick } from "vue";
import { useUserPinia } from "@/pinia/user";
import { ElMessage } from "element-plus";
import selectBirth from "@/components/selectBirth.vue";
import selectArea from "@/components/selectArea.vue";
import areaDatas from "@/staticDatas/area";

const userStore = useUserPinia();

const props = defineProps<{
  modelValue: string;
}>();

const emits = defineEmits<{
  (e: "update:modelValue", name: string): void;
}>();

/**
 * 用户的信息属性对象
 */
const userInfo = reactive<{
  sex: "男" | "女";
  birthday: Date;
  /**
   * 对应的区域，元组类型，第一个为省份的id值，第二个为对应省份的城市的id值
   */
  areaCoord: [number, number];
}>({
  sex: "男",
  birthday: new Date(),
  areaCoord: [0, 0],
});

/****************************************** 修改昵称逻辑  */
/**
 * 创建自定义响应属性
 * @param value - 属性值
 */
const useRef = (value: string) =>
  customRef((track, trigger) => ({
    get(): string {
      track();
      return value;
    },
    set(newValue: string): void {
      value = newValue.trim();
      trigger();
    },
  }));
/**
 * 给昵称输入框一个ref属性
 */
const nickNameRef = ref<HTMLInputElement>();
/**
 * 用户的昵称
 */
const nickName = useRef("");
/**
 * 更新nickName值
 */
const updateNickName = () => {
  if (nickName.value !== userStore.user.nickName)
    nickName.value = userStore.user.nickName;
};
/**
 * 文本段落的组成是否完成或取消时
 */
const isCompositEnd = ref<boolean>(true);

// 开始输入中文
const compositStart = () => {
  isCompositEnd.value = false;
};
// 输入中文结束
const compositEnd = (e: Event) => {
  isCompositEnd.value = true;
  handleInput(e);
};
const handleInput = (e: Event) => {
  if (isCompositEnd.value) nickName.value = (e.target as HTMLInputElement).value;
};

/**
 * 是否正在更改昵称
 */
const isLoading__nickName = ref<boolean>(false);

// 开始更改昵称
const changeNickName = (): void => {
  if (nickName.value === userStore.user.nickName) {
    ElMessage({
      duration: 1500,
      message: "不能和原昵称相同",
      type: "error",
    });
    return;
  }
  isLoading__nickName.value = true;
  userStore
    .changeNickName({ nickName: nickName.value })
    .then((code: number) => {
      isLoading__nickName.value = false;
      if (code === 1)
        ElMessage({
          duration: 1500,
          message: "设置成功",
          type: "success",
        });
      else
        ElMessage({
          duration: 1500,
          message: "设置失败",
          type: "error",
        });
      nextTick(() => nickNameRef.value?.focus());
    })
    .catch(() => {
      isLoading__nickName.value = false;
      nextTick(() => nickNameRef.value?.focus());
      ElMessage({
        duration: 1500,
        message: "设置失败",
        type: "error",
      });
    });
};

// 用户按下Enter键是否开始发送请求
const isChangeNickName = () => {
  if (nickName.value) changeNickName();
  else
    ElMessage({
      type: "error",
      message: "昵称不能为空",
      duration: 1500,
    });
};

/****************************************** 修改性别逻辑  */
/**
 * 是否正在更改性别
 */
const isLoading__sex = ref<boolean>(false);

// 开始更改性别
const changeSex = (): void => {
  if (userInfo.sex === userStore.user.sex) {
    ElMessage({
      duration: 1500,
      message: "不能和原性别相同",
      type: "error",
    });
    return;
  }
  isLoading__sex.value = true;
  userStore
    .changeSex({ sex: userInfo.sex })
    .then((code: number) => {
      isLoading__sex.value = false;
      if (code === 1)
        ElMessage({
          duration: 1500,
          message: "设置成功",
          type: "success",
        });
      else
        ElMessage({
          duration: 1500,
          message: "设置失败",
          type: "error",
        });
    })
    .catch(() => {
      isLoading__sex.value = false;
      ElMessage({
        duration: 1500,
        message: "设置失败",
        type: "error",
      });
    });
};

/****************************************** 修改生日逻辑  */
/**
 * 是否正在更改生日
 */
const isLoading__birthday = ref<boolean>(false);

// 开始更改生日
const changeBirth = (): void => {
  if (userInfo.birthday === userStore.user.birthday) {
    ElMessage.error("不能和原生日相同");
    return;
  }
  isLoading__birthday.value = true;
  userStore
    .changeBirth({ birthday: userInfo.birthday })
    .then((code: number) => {
      isLoading__birthday.value = false;
      if (code === 1)
        ElMessage({
          duration: 1500,
          message: "设置成功",
          type: "success",
        });
      else
        ElMessage({
          duration: 1500,
          message: "设置失败",
          type: "error",
        });
    })
    .catch(() => {
      isLoading__birthday.value = false;
      ElMessage({
        duration: 1500,
        message: "设置失败",
        type: "error",
      });
    });
};

/****************************************** 修改区域逻辑  */
/**
 * 是否正在更改区域
 */
const isLoading__area = ref<boolean>(false);

// 开始更改区域
const changeArea = (): void => {
  if (
    userInfo.areaCoord[0] === userStore.user.areaCoord[0] &&
    userInfo.areaCoord[1] === userStore.user.areaCoord[1]
  ) {
    ElMessage({
      duration: 1500,
      message: "不能和原区域相同",
      type: "error",
    });
    return;
  }
  isLoading__area.value = true;
  userStore
    .changeArea({
      area: `${areaDatas[userInfo.areaCoord[0]].value} ${
        areaDatas[userInfo.areaCoord[0]].children[userInfo.areaCoord[1]].value
      }`,
      areaCoord: userInfo.areaCoord,
    })
    .then((code: number) => {
      isLoading__area.value = false;
      if (code === 1)
        ElMessage({
          duration: 1500,
          message: "设置成功",
          type: "success",
        });
      else
        ElMessage({
          duration: 1500,
          message: "设置失败",
          type: "error",
        });
    })
    .catch(() => {
      isLoading__area.value = false;
      ElMessage({
        duration: 1500,
        message: "设置失败",
        type: "error",
      });
    });
};

/**
 * 当前标签页的名称name
 */
const activeName = ref<string>("nickName");

watch(
  () => activeName.value,
  (name: string) => {
    // 如果切换到修改昵称标签时则该输入框聚焦
    switch (name) {
      case "nickName":
        updateNickName();
        nextTick(() => nickNameRef.value?.focus());
        break;
      case "sex":
        userInfo.sex = userStore.user.sex;
        break;
      case "birthday":
        nextTick(() => (userInfo.birthday = userStore.user.birthday));
        break;
      case "area":
        nextTick(() => (userInfo.areaCoord = userStore.user.areaCoord));
        break;
    }
    emits("update:modelValue", name);
  }
);

watch(
  () => props.modelValue,
  (name: string) => (activeName.value = name)
);

onMounted(() => (activeName.value = props.modelValue));

defineExpose({
  updateNickName,
});
</script>

<style lang="scss" scoped>
.info-manage {
  width: 85%;
  margin: 0 auto;

  &__nickname {
    margin: 25px 0;
    padding: 5px 0 5px;
    background-color: rgb(248, 248, 248);
    border: {
      top: 0;
      left: 0;
      right: 0;
      bottom: 1.5px solid #e4e7ed;
    }
    outline: none;
    width: 60%;
    font-size: 17px;
  }

  &__birth {
    width: 85%;
    margin: -5px 0 -65px;

    &--button {
      width: 80%;
      margin: 20px 0 0 10px;
    }
  }

  &__area--button {
    width: 60%;
    margin: 20px 0 0 20px;
  }
}
</style>
